home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $PROJECT: binary.datatype
- **
- ** $VER: dispatch.c 39.11 (11.04.95)
- **
- ** by
- **
- ** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
- **
- ** (C) Copyright 1994,1995
- ** All Rights Reserved !
- **
- ** $HISTORY:
- **
- ** 11.04.95 : 039.011 : new DTBM_#? methods,DTM_TRIGGER and DTM_DRAW methods
- ** 19.02.95 : 039.010 : fixed bug,which caused a crash ,if the display width was
- ** less than the required width for the offsets.
- ** prefs file parsing now via ReadArgs().
- ** new prefs directory : 'Env:DataTypes' .
- ** 28.01.95 : 039.009 : fixed down scrolling bug, which skipped one line
- ** 22.01.95 : 039.008 : now supports DTM_PRINT method and searchs for PROGDIR:binary.prefs
- ** 21.01.95 : 039.007 : bug fixed. Rendering address higher than the file length (small files)
- ** 28.12.94 : 039.006 : now it's a base datatype and no async layout is needed
- ** 24.11.94 : 039.005 : memory handling improved, layout only performed if needed
- ** 18.11.94 : 039.004 : added PREFS file
- ** 16.11.94 : 039.003 : BDTDH_NONE now works
- ** 15.11.94 : 039.002 : added BDTA_BytesPerLine,BDTA_DisplayHex and BDTA_ShowASCII attrs
- ** 13.11.94 : 039.001 : initial
- */
-
- /* ------------------------------- include -------------------------------- */
-
- #include "classbase.h"
-
- /* ------------------------------- autodoc -------------------------------- */
-
- /*FS*/ /*"AutoDoc"*/
- /*GB*** binary.datatype/binary.datatype **************************************
- *
- * NAME
- * binary.datatype -- data type for any binary file
- *
- * FUNCTION
- * The binary data type, a base-class of all binary data, is used to
- * load any binary file and displays the contents of the file in hex
- * format.
- *
- * PREFS
- * The data type tries to load the prefs file first from
- * "PROGDIR:Prefs/DataTypes/binary.prefs" and then
- * "ENV:DataTypes/binary.prefs" on each OM_NEW method to set up the
- * attributes !
- * Up from version 39.10 it uses the ReadArgs() function to parse the
- * prefs file. The template is :
- *
- * NOASCII/S,NOWRAP/S,NONE/S,BYTE/S,WORD/S,LONG/S,BPL=BYTESPERLINE/N/K
- *
- * NOASCII - sets BDTA_ShowASCII to FALSE
- * NOWRAP - sets BDTA_DisplayWrap to FALSE
- * NONE - sets BDTA_DisplayHex to BDTDH_NONE
- * BYTE - sets BDTA_DisplayHex to BDTDH_BYTE
- * WORD - sets BDTA_DisplayHex to BDTDH_WORD
- * LONG - sets BDTA_DisplayHex to BDTDH_LONG
- * BYTESPERLINE <bpl> or
- * BPL <bpl> - sets BDTA_BytesPerLine to <bpl> bytes
- *
- * The options can be on several lines !
- *
- * METHODS
- * OM_NEW -- Create a new text object from a binary file in hex mode.
- *
- * OM_DISPOSE -- dispose a object
- *
- * OM_GET -- get a attribute of the object
- *
- * OM_SET -- set attributes of the object
- *
- * OM_UPDATE -- update some attributes of the object
- *
- * GM_LAYOUT -- Method to layout the hex text
- *
- * GM_RENDER -- draw the object
- *
- * DTM_WRITE -- DTWM_RAW mode is supported
- *
- * DTM_PRINT -- prints the hex text
- *
- * DTM_DRAW -- draws the datatype in the given RastPort (This is
- * expermintal, I use this method for my new text.datatype to
- * embed other datatype objects ! Don't use this at the moment !)
- *
- * DTM_TRIGGER -- trigger methods to let the user input a search string
- * and to search next or previous occurence of that string :
- * STM_ACTIVATE_FIELD (return) - opens the string requester. This
- * requester is spawned asyncronly !
- * STM_BROWSE_NEXT ('>') - searchs next occurence
- * STM_BROWSE_PREV ('<') - searchs previous occurence
- *
- * DTBM_GETSTRING -- opens a requester to let the user input the
- * string !
- *
- * DTBM_SEARCHNEXT -- searchs for the next occurence of the specified
- * string
- *
- * DTBM_SEARCHPREV -- searchs for the previous occurance of the given
- * string
- *
- * TAGS
- * BDTA_Buffer -- (UBYTE *) pointer to the buffer, which should be
- * displayed.
- * Applicability is (ISG).
- *
- * BDTA_BufferLen -- (ULONG) length of the buffer supplied with
- * BDTA_Buffer tag. This must be given if the buffer tag is
- * specified.
- * Applicability is (ISG).
- *
- * BDTA_BytesPerLine -- (UWORD) number of bytes per line.
- * If BDTA_DisplayHex is BDTDH_WORD it must be a multiply of 2,
- * if it is BDTDH_LONG it must be a multiply of 4 !
- * Default is 32.
- * Applicability is (ISGNU).
- *
- * BDTA_DisplayHex -- (UWORD) type of the display. The following types
- * are supported : BDTDH_NONE - displays no hex values
- * BDTDH_BYTE - displays each byte in hex ( 8 bit)
- * BDTDH_WORD - displays each word in hex (16 bit)
- * BDTDH_LONG - displays each long in hex (32 bit)
- * Default is BDTDH_LONG.
- * Applicability is (ISGNU).
- *
- * BDTA_ShowASCII -- (BOOL) display at the end of the line the
- * appropriate ASCII string !
- * Default is TRUE.
- * Applicability is (ISGNU).
- *
- * BDTA_DisplayWrap -- (BOOL) the BDTA_BytesPerLine are ignored and the
- * byte number is retrieved from the object width !
- * Default is TRUE.
- * Applicability is (ISGNU).
- *
- * BDTA_Found -- (STRPTR) pointer to the buffer to highlight the line.
- * This is used to display the line of a found string !
- * Default is NULL
- * Applicability is (ISNU).
- *
- * BUGS
- * At the moment proportional fonts can't be handled.
- *
- * SEE ALSO
- * datatypesclass (where ?)
- *
- ******************************************************************************
- *
- */
- /*FE*/
-
- /* ------------------------------- defines -------------------------------- */
-
- #define G(o) ((struct Gadget *) (o))
- #define GPR(msg) ((struct gpRender *) (msg))
- #define SET(msg) ((struct opSet *) (msg))
- #define WRMSG(msg) ((struct dtWrite *) (msg))
- #define DRMSG(msg) ((struct dtDraw *) (msg))
- #define FRBOX(msg) ((struct dtFrameBox *) (msg))
- #define TRG(msg) ((struct dtTrigger *) (msg))
- #define SMSG(msg) ((struct dtbSearch *) (msg))
- #define GSMSG(msg) ((struct dtbGetString *) (msg))
-
- #define prefstemplate "NOASCII/S,NOWRAP/S,NONE/S,BYTE/S,WORD/S,LONG/S,BPL=BYTESPERLINE/N/K"
-
- enum
- {
- PREFSARG_NOASCII,
- PREFSARG_NOWRAP,
- PREFSARG_NONE,
- PREFSARG_BYTE,
- PREFSARG_WORD,
- PREFSARG_LONG,
- PREFSARG_BYTESPERLINE,
- PREFSARG_MAX
- };
-
- /* ---------------------------- instance data ----------------------------- */
-
- struct BinaryData
- {
- UBYTE *bd_Buffer;
- UBYTE *bd_BufferEnd;
- ULONG bd_BufferLen;
-
- UWORD bd_Flags;
- UWORD bd_DisplayHex;
- UWORD bd_BytesPerLine;
-
- UWORD bd_NumGroups;
- UWORD bd_LineBytes;
-
- UWORD bd_LineBufferLen;
- UBYTE *bd_LineBuffer;
-
- ULONG bd_OldX;
- ULONG bd_OldY;
-
- /* font support */
- struct TextFont *bd_Font;
- struct TextAttr bd_TextAttr;
- UBYTE bd_FontName[MAXFONTNAME];
-
- UBYTE bd_Name[256];
-
- UBYTE bd_InputString[80];
- UBYTE bd_SearchString[80];
-
- STRPTR bd_Found;
-
- struct dtbGetString bd_GetStringMsg;
- };
-
- #define BDF_SHOWASCII (1<<0)
- #define BDF_ALLOCATED (1<<1)
- #define BDF_DISPLAYWRAP (1<<2)
- #define BDF_NEEDLAYOUT (1<<3)
- #define BDF_NEEDRENDERING (1<<4)
-
- /* ---------------------------- constant data ----------------------------- */
-
- const ULONG methods[] = {
- OM_NEW,
- OM_DISPOSE,
- OM_GET,
- OM_SET,
- OM_UPDATE,
- GM_LAYOUT,
- GM_RENDER,
- DTM_WRITE,
- DTM_PRINT,
- DTM_DRAW,
- DTM_FRAMEBOX,
- ~0};
-
- /* ------------------------------ init class ------------------------------ */
-
- /*FS*/ LibCall Class *initClass(REGA6 struct ClassBase *cb)
- {
- Class *cl;
-
- D(bug("init binary.datatype !\n"));
-
- if((cl = MakeClass("binary.datatype","datatypesclass",NULL,sizeof(struct BinaryData),0)))
- {
- cl->cl_Dispatcher.h_Entry = (HOOKFUNC) dispatch;
- cl->cl_UserData = (ULONG) cb;
-
- AddClass(cl);
- }
-
- return(cl);
- }
- /*FE*/
-
- /* -------------------------- support functions --------------------------- */
-
- /*FS*/ BOOL readPrefs(struct ClassBase *cb,struct BinaryData *bd,STRPTR file)
- {
- struct RDArgs *rdargs;
- struct RDArgs *args;
- BPTR fh;
-
- ENTERING;
-
- if((fh = Open(file,MODE_OLDFILE)))
- {
- UBYTE buf[256];
- ULONG para[PREFSARG_MAX];
- LONG i;
-
- DB(("def file %s opened\n",file));
-
- while(FGets(fh,buf,sizeof(buf)))
- {
- DB(("line : %s",buf));
-
- if((rdargs = (struct RDArgs *) AllocDosObject(DOS_RDARGS,NULL)))
- {
- rdargs->RDA_Source.CS_Buffer = buf;
- rdargs->RDA_Source.CS_Length = strlen(buf);
-
- for(i=0 ; i < (sizeof(para)/sizeof(LONG)) ; i++)
- para[i]=0;
-
- DB(("rdargs at : %lx\n",rdargs));
-
- if((args = ReadArgs(prefstemplate,(LONG *) para,rdargs)))
- {
- DB(("args at %lx\n",args));
-
- if(para[PREFSARG_NOASCII])
- bd->bd_Flags &= ~BDF_SHOWASCII;
-
- if(para[PREFSARG_NOWRAP])
- bd->bd_Flags &= ~BDF_DISPLAYWRAP;
-
- if(para[PREFSARG_NONE])
- bd->bd_DisplayHex = BDTDH_NONE;
-
- if(para[PREFSARG_BYTE])
- bd->bd_DisplayHex = BDTDH_BYTE;
-
- if(para[PREFSARG_WORD])
- bd->bd_DisplayHex = BDTDH_WORD;
-
- if(para[PREFSARG_LONG])
- bd->bd_DisplayHex = BDTDH_LONG;
-
- if(para[PREFSARG_BYTESPERLINE])
- {
- bd->bd_BytesPerLine = (UWORD) *((LONG *) para[PREFSARG_BYTESPERLINE]);
-
- if(bd->bd_BytesPerLine < 4)
- bd->bd_BytesPerLine = 4;
- if(bd->bd_BytesPerLine > (1<<16))
- bd->bd_BytesPerLine = 32;
- }
- }
- FreeDosObject(DOS_RDARGS , rdargs);
- }
- }
- Close(fh);
- }
-
- LEAVING;
-
- return((BOOL) (fh == NULL));
- }
- /*FE*/
-
- /*FS*/ void useDefaultFont(struct ClassBase *cb,struct BinaryData *bd)
- {
- struct TextFont *deffont;
-
- D(bug("using default font !\n"));
-
- #undef GfxBase
- deffont = ((struct GfxBase *) cb->cb_GfxBase)->DefaultFont;
- #define GfxBase cb->cb_GfxBase
-
- bd->bd_TextAttr.ta_YSize = deffont->tf_YSize;
- bd->bd_TextAttr.ta_Style = FS_NORMAL;
- bd->bd_TextAttr.ta_Flags = deffont->tf_Flags;
- bd->bd_TextAttr.ta_Name = bd->bd_FontName;
- strcpy(bd->bd_TextAttr.ta_Name,deffont->tf_Message.mn_Node.ln_Name);
-
- bd->bd_Font = OpenFont(&bd->bd_TextAttr);
- }
- /*FE*/
-
- /* --------------------------- class dispatcher --------------------------- */
-
- /*FS*/ ClassCall ULONG dispatch(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg)
- {
- struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
- struct BinaryData *bd = INST_DATA(cl,obj);
- ULONG retval = 0;
-
- switch(msg->MethodID)
- {
- case OM_NEW:
- {
- Object *newobj;
- if((newobj = (Object *) DoSuperMethodA(cl,obj,msg)))
- {
- bd = INST_DATA(cl,newobj);
-
- /* set default setting */
- bd->bd_BytesPerLine = 32;
- bd->bd_DisplayHex = BDTDH_LONG;
- bd->bd_Flags = BDF_SHOWASCII | BDF_DISPLAYWRAP;
-
- /* read default user settings */
- if(readPrefs(cb,bd,"PROGDIR:Prefs/DataTypes/binary.prefs"))
- readPrefs(cb,bd,"ENV:DataTypes/binary.prefs");
-
- setattrs(cl,newobj,(struct opSet *) msg);
-
- /* use default textfont */
- if(!bd->bd_Font)
- useDefaultFont(cb,bd);
-
- /* if no buffer is provided , get the handle from the superclass
- and load the file in the buffer */
- if(!bd->bd_Buffer)
- {
- BPTR fh;
- ULONG type;
- LONG num;
-
- if(((num = GetDTAttrs((Object *) newobj,DTA_Handle ,&fh,
- DTA_SourceType ,&type,
- TAG_DONE)) == 2) && fh)
- {
- struct FileInfoBlock *fib;
-
- D(bug("type : %ld\n",type));
-
- switch(type)
- {
- case DTST_FILE:
- if((fib = AllocDosObject(DOS_FIB,NULL)))
- {
- if(ExamineFH(fh,fib) && fib->fib_Size > 0)
- {
- if((bd->bd_Buffer = AllocMem(fib->fib_Size,MEMF_ANY)))
- {
- bd->bd_Flags |= BDF_ALLOCATED;
- bd->bd_BufferLen = fib->fib_Size;
- bd->bd_BufferEnd = &bd->bd_Buffer[fib->fib_Size];
- Seek(fh,0,OFFSET_BEGINNING);
- Read(fh,bd->bd_Buffer,bd->bd_BufferLen);
- }
- }
- }
- FreeDosObject(DOS_FIB,fib);
- if(!NameFromFH(fh,bd->bd_Name,sizeof(bd->bd_Name)))
- strcpy(bd->bd_Name,"unknown");
- break;
- case DTST_RAM:
- strcpy(bd->bd_Name,"RAM");
- break;
- default:
- D(bug("not supported SourceType : %ld\n",type));
- }
-
- }
- }
-
- if(bd->bd_Buffer)
- {
- retval = (ULONG) newobj;
- setSuperAttrs(cl,newobj,NULL,GA_RelSpecial,TRUE,TAG_DONE);
- ((struct ExtGadget *) newobj)->MoreFlags = GMORE_SCROLLRASTER;
- } else /* something was going wrong, thus dispose myself */
- {
- D(bug("binary.datatype error : %ld\n",IoErr()));
- CoerceMethod(cl,(Object *) retval,OM_DISPOSE);
- }
- }
- }
- break;
- case OM_DISPOSE:
- if(bd->bd_Buffer && (bd->bd_Flags & BDF_ALLOCATED))
- FreeMem(bd->bd_Buffer,bd->bd_BufferLen);
-
- if(bd->bd_LineBuffer && bd->bd_LineBufferLen)
- FreeMem(bd->bd_LineBuffer,bd->bd_LineBufferLen);
-
- if(bd->bd_Font)
- CloseFont(bd->bd_Font);
-
- retval = DoSuperMethodA(cl,obj,msg);
- break;
- case OM_UPDATE:
- case OM_SET:
- if((retval = setattrs(cl,obj,(struct opSet *) msg)))
- if(bd->bd_Flags & BDF_NEEDLAYOUT)
- {
- DoMethod(obj,GM_LAYOUT,((struct opSet *) msg)->ops_GInfo,TRUE);
- bd->bd_Flags &= ~BDF_NEEDLAYOUT;
- }
-
- /* Pass the attributes to the super class and force a refresh
- * if we need it */
- if((retval += DoSuperMethodA (cl, obj, msg)) && (OCLASS (obj) == cl))
- {
- struct RastPort *rp;
-
- /* Get a pointer to the rastport */
- if((rp = ObtainGIRPort (((struct opSet *) msg)->ops_GInfo)))
- {
- DB(("update calls GM_RENDER\n"));
-
- /* Force a redraw */
- DoMethod(obj,GM_RENDER,((struct opSet *) msg)->ops_GInfo,rp,GREDRAW_REDRAW);
-
- /* Release the temporary rastport */
- ReleaseGIRPort (rp);
- }
-
- if(msg->MethodID == OM_UPDATE)
- DoMethod(obj,OM_NOTIFY,SET(msg)->ops_AttrList,SET(msg)->ops_GInfo,0);
-
- retval = 0;
- }
- break;
- case OM_GET:
- if(!(retval = getattr(cl,obj,(struct opGet *) msg)))
- retval = DoSuperMethodA(cl,obj,msg);
- break;
- case GM_LAYOUT:
- /* Tell everyone that we are busy doing things */
- notifyAttrChanges (obj, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
- GA_ID, G(obj)->GadgetID,
- DTA_Busy, TRUE,
- TAG_DONE);
-
- /* Let the super-class partake */
- retval = DoSuperMethodA (cl, obj, msg);
-
- retval += layout(cb, cl, obj, (struct gpLayout *) msg);
-
- break;
- case GM_RENDER:
- {
- struct RastPort *rp = GPR(msg)->gpr_RPort;
- struct Rectangle rect;
- struct IBox *domain;
- ULONG x,y;
- ULONG ux,uy;
- ULONG py,px;
- LONG topy,topx,num;
- LONG w,h;
- LONG dx,dy,height;
- LONG chrs;
-
- STRPTR ptr,old;
-
- UBYTE fgpen = 1;
- UBYTE bgpen = 0;
-
- D(bug("draw mode : %lx\n",GPR(msg)->gpr_Redraw));
-
- if(GetDTAttrs(obj,DTA_TopVert ,&y,
- DTA_TopHoriz ,&x,
- DTA_VisibleVert ,&h,
- DTA_VisibleHoriz,&w,
- DTA_VertUnit ,&uy,
- DTA_HorizUnit ,&ux,
- DTA_Domain ,&domain,
- TAG_DONE) == 7)
- {
- topy = y;
- topx = x;
-
- height = (h-1) * uy;
-
- rect.MinX = domain->Left;
- rect.MinY = domain->Top;
- rect.MaxX = domain->Left + w * ux - 1;
- rect.MaxY = domain->Top + h * uy - 1;
-
- SetFont(GPR(msg)->gpr_RPort,bd->bd_Font);
- SetABPenDrMd(rp,fgpen,bgpen,JAM2);
-
- y *= uy;
- x *= ux;
-
- dx = (x - bd->bd_OldX);
- dy = (y - bd->bd_OldY);
-
- bd->bd_OldX = x;
- bd->bd_OldY = y;
-
- if(dx > domain->Width/2 || dx <-domain->Width/2 || bd->bd_Found)
- dx = 0;
-
- if(dy > height/2 || dy < -height/2 || bd->bd_Found)
- dy = 0;
-
- py = 0;
- px = 0;
-
- if(dx || dy)
- ScrollRasterBF(rp,dx,dy,
- rect.MinX,rect.MinY,rect.MaxX,rect.MaxY);
-
- D(bug("dx : %ld , dy : %ld\n",dx,dy));
-
- if(dx == 0)
- {
- if(dy < 0)
- height = -dy;
- else if(dy > 0)
- {
- py = height - dy;
- topy += ((domain->Height / uy) - dy/uy) - 1;
- }
- } else if(dx > 0)
- {
- px = w * ux - dx;
- topx += (w - (dx/ux));
- w = dx/ux;
- } else
- {
- w = (-dx/ux);
- }
-
- num = topy * bd->bd_BytesPerLine;
- ptr = &bd->bd_Buffer[num];
-
- D(bug("py : %ld , height : %ld , topy : %ld\n",py,height,topy));
-
- for(; py <= height && ptr < bd->bd_BufferEnd ; py += rp->TxHeight)
- {
- if(SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
- break;
-
- old = ptr;
-
- if((chrs = formatline(bd,&ptr,bd->bd_LineBuffer,num) - topx) > w)
- chrs = w;
-
- if(chrs > 0)
- {
- Move(rp,domain->Left + px,domain->Top + py + rp->TxBaseline);
- Text(rp,&bd->bd_LineBuffer[topx],chrs);
-
- if(bd->bd_Found >= old && bd->bd_Found <= ptr)
- {
- SetDrMd(rp,COMPLEMENT);
- RectFill(rp,domain->Left + px,domain->Top + py,domain->Left + px + TextLength(rp,&bd->bd_LineBuffer[topx],chrs) - 1,domain->Top + py + rp->TxHeight - 1);
- SetDrMd(rp,JAM2);
- }
- }
-
- num += bd->bd_BytesPerLine;
- }
- DB(("after rendering !\n"));
- }
- }
- break;
- case DTM_WRITE:
- switch(WRMSG(msg)->dtw_Mode)
- {
- case DTWM_RAW:
- D(bug("dtWrite Rawmode : filehandle %lx !\n",WRMSG(msg)->dtw_FileHandle));
- D(bug("attrs at : %lx\n",WRMSG(msg)->dtw_AttrList));
- D({
- struct TagItem *tstate = WRMSG(msg)->dtw_AttrList;
- struct TagItem *tag;
-
- while((tag = NextTagItem(&tstate)))
- bug("{%08lx,%ld}\n",tag->ti_Tag,tag->ti_Data);
- });
-
- Write(WRMSG(msg)->dtw_FileHandle,bd->bd_Buffer,bd->bd_BufferLen);
- retval = 1;
- break;
- default:
- retval = DoSuperMethodA(cl,obj,msg);
- }
- break;
- case DTM_PRINT:
- {
- union printerIO *pio = ((struct dtPrint *) msg)->dtp_PIO;
- STRPTR ptr;
- STRPTR buf;
- LONG len;
- ULONG num = 0;
-
- ptr = &bd->bd_Buffer[0];
-
- if((buf = AllocVec(bd->bd_LineBufferLen,MEMF_ANY)))
- {
- pio->ios.io_Command = CMD_WRITE;
- pio->ios.io_Data = buf;
-
- while(ptr < bd->bd_BufferEnd && pio->ios.io_Error == 0)
- {
- len = formatline(bd,&ptr,buf,num);
-
- if(len > 0)
- {
- buf[len] = '\n';
- pio->ios.io_Length = len + 1;
- DoIO((struct IORequest *) &pio->ios);
- }
- num += bd->bd_BytesPerLine;
- }
- FreeVec(buf);
- }
- }
- break;
- /* this method is experimental ! My new text.datatype (should) support of
- * embedding any datatype, which implements this DTM_DRAW method ! Don't
- * use this at the moment!
- */
- case DTM_DRAW:
- {
- struct RastPort *rp = DRMSG(msg)->dtd_RPort;
- STRPTR ptr;
- ULONG py;
- LONG topy,topx;
- LONG w,h;
- LONG height,num;
- LONG chrs;
-
- topy = DRMSG(msg)->dtd_TopVert;
- topx = DRMSG(msg)->dtd_TopHoriz;
- height = DRMSG(msg)->dtd_Height;
-
- w = DRMSG(msg)->dtd_Width / rp->TxWidth;
- h = DRMSG(msg)->dtd_Height / rp->TxHeight;
-
- num = topy * bd->bd_BytesPerLine;
- ptr = &bd->bd_Buffer[num];
-
- for(py = 0; py < height && ptr < bd->bd_BufferEnd ; py += rp->TxHeight)
- {
- if((chrs = formatline(bd,&ptr,bd->bd_LineBuffer,num) - topx) > w)
- chrs = w;
-
- if(chrs > 0)
- {
- Move(rp,DRMSG(msg)->dtd_Left,DRMSG(msg)->dtd_Top + py + rp->TxBaseline);
- Text(rp,&bd->bd_LineBuffer[topx],chrs);
- }
-
- num += bd->bd_BytesPerLine;
- }
- }
- retval = 1;
- break;
- case DTM_FRAMEBOX:
- {
- ULONG ux,uy;
- ULONG w,h;
- retval = 0;
-
- if(GetDTAttrs(obj,DTA_TotalVert ,&h,
- DTA_TotalHoriz ,&w,
- DTA_VertUnit ,&uy,
- DTA_HorizUnit ,&ux,
- TAG_DONE) == 4)
- {
- if(FRBOX(msg)->dtf_FrameInfo)
- {
- FRBOX(msg)->dtf_FrameInfo->fri_Dimensions.Height = h * uy;
- FRBOX(msg)->dtf_FrameInfo->fri_Dimensions.Width = w * ux;
- FRBOX(msg)->dtf_FrameInfo->fri_Dimensions.Depth = 1;
- FRBOX(msg)->dtf_FrameInfo->fri_Flags = FIF_SCROLLABLE;
- retval = 1;
- }
- }
- }
- break;
-
- /* trigger interface for the search string requester , this must be asyncron ! */
- case DTM_TRIGGER:
- {
- ULONG searchmethod = DTBM_SEARCHNEXT;
- D(bug("trigger method : %ld,GInfo 0x%lx\n",TRG(msg)->dtt_Function,TRG(msg)->dtt_GInfo));
-
- switch(TRG(msg)->dtt_Function)
- {
- case STM_BROWSE_PREV:
- searchmethod = DTBM_SEARCHPREV;
- case STM_BROWSE_NEXT:
- if(bd->bd_InputString[0])
- {
- DoMethod(obj,searchmethod,TRG(msg)->dtt_GInfo,bd->bd_SearchString,strlen(bd->bd_SearchString));
- break;
- }
- case STM_ACTIVATE_FIELD:
- bd->bd_GetStringMsg.MethodID = DTBM_GETSTRING;
- bd->bd_GetStringMsg.dtbgs_GInfo = TRG(msg)->dtt_GInfo;
- bd->bd_GetStringMsg.dtbgs_SearchMethod = searchmethod;
- DoAsyncMethodA(obj,(Msg) &bd->bd_GetStringMsg,NULL);
- break;
- }
- }
- break;
- /* the real stringrequester method */
- case DTBM_GETSTRING:
- retval = getstring(cl,obj,(struct dtbGetString *) msg);
- DB(("after getstring\n"));
- break;
- case DTBM_SEARCHNEXT:
- case DTBM_SEARCHPREV:
- {
- UBYTE *ptr = bd->bd_Found;
-
- if(!ptr)
- ptr = bd->bd_Buffer;
-
- D(bug("search for : %s, len = %ld\n",SMSG(msg)->dtbs_Search,
- SMSG(msg)->dtbs_SearchLength));
-
- if(msg->MethodID == DTBM_SEARCHNEXT)
- ptr = searchstring(ptr + 2,
- bd->bd_BufferEnd - ptr,
- SMSG(msg)->dtbs_Search,
- SMSG(msg)->dtbs_SearchLength,
- 1);
- else
- {
- ptr += (SMSG(msg)->dtbs_SearchLength - 2);
- if(ptr >= bd->bd_BufferEnd)
- ptr = bd->bd_BufferEnd - 1;
-
- if((ptr = searchstring(ptr,
- ptr - bd->bd_Buffer,
- SMSG(msg)->dtbs_Search,
- SMSG(msg)->dtbs_SearchLength,
- -1)))
- {
- ptr -= SMSG(msg)->dtbs_SearchLength;
- }
- }
-
- D(bug("found at : %lx\n",ptr));
-
- setAttrs(obj,SMSG(msg)->dtbs_GInfo,BDTA_Found,ptr,TAG_DONE);
- }
- break;
- default:
- retval = DoSuperMethodA(cl,obj,msg);
- }
-
- return(retval);
- }
- /*FE*/
-
- /*FS*/ ULONG getattr(Class *cl,Object *obj,struct opGet *msg)
- {
- struct BinaryData *bd = INST_DATA(cl,obj);
- ULONG *storage = msg->opg_Storage;
-
- switch(msg->opg_AttrID)
- {
- case DTA_TextFont:
- *storage = (ULONG) bd->bd_Font;
- break;
- case DTA_TextAttr:
- *storage = (ULONG) &bd->bd_TextAttr;
- break;
- case DTA_Methods:
- *storage = (ULONG) methods;
- break;
- case BDTA_Buffer:
- *storage = (ULONG) bd->bd_Buffer;
- break;
- case BDTA_BufferLen:
- *storage = (ULONG) bd->bd_BufferLen;
- break;
- case BDTA_BytesPerLine:
- *storage = (ULONG) bd->bd_BytesPerLine;
- break;
- case BDTA_DisplayHex:
- *storage = (ULONG) bd->bd_DisplayHex;
- break;
- case BDTA_ShowASCII:
- *storage = (ULONG) ((bd->bd_Flags & BDF_SHOWASCII) == BDF_SHOWASCII);
- break;
- case BDTA_DisplayWrap:
- *storage = (ULONG) ((bd->bd_Flags & BDF_DISPLAYWRAP) == BDF_DISPLAYWRAP);
- break;
- default:
- return(0);
- }
- return(1);
- }
- /*FE*/
- /*FS*/ ULONG setattrs(Class *cl,Object *obj,struct opSet *msg)
- {
- struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
- struct BinaryData *bd = INST_DATA(cl,obj);
-
- struct TagItem *tstate = msg->ops_AttrList;
- struct TagItem *tag;
-
- ULONG retval = 0;
- ULONG tidata;
-
- while((tag = NextTagItem(&tstate)))
- {
- tidata = tag->ti_Data;
-
- DB(("tag : {0x%08lx,0x%08lx}\n",tag->ti_Tag,tidata));
- retval++;
- switch(tag->ti_Tag)
- {
- case DTA_TextAttr:
- {
- struct TextFont *font;
-
- if((font = OpenFont((struct TextAttr *) tidata)))
- {
- /* only use fixed width fonts */
- if(font->tf_Flags & FPF_PROPORTIONAL)
- {
- CloseFont(font);
- useDefaultFont(cb,bd);
- } else
- {
- bd->bd_TextAttr = *((struct TextAttr *) tidata);
- bd->bd_TextAttr.ta_Name = bd->bd_FontName;
- strcpy(bd->bd_FontName,((struct TextAttr *) tidata)->ta_Name);
-
- if(bd->bd_Font)
- CloseFont(bd->bd_Font);
-
- bd->bd_Font = font;
- }
- bd->bd_Flags |= BDF_NEEDLAYOUT;
- } else
- retval--;
- }
- break;
- case BDTA_Buffer:
- {
- ULONG len = GetTagData(BDTA_BufferLen,0,msg->ops_AttrList);
-
- if(tidata && len)
- {
- if((bd->bd_Buffer) && (bd->bd_Flags & BDF_ALLOCATED))
- FreeMem(bd->bd_Buffer,bd->bd_BufferLen);
-
- bd->bd_Flags &= ~BDF_ALLOCATED;
-
- bd->bd_Buffer = (UBYTE *) tidata;
- bd->bd_BufferLen = len;
- bd->bd_BufferEnd = &bd->bd_Buffer[len];
- bd->bd_Flags |= BDF_NEEDLAYOUT;
-
- retval++;
- } else
- retval--;
- }
- break;
- case BDTA_BytesPerLine:
- if(tidata != bd->bd_BytesPerLine)
- {
- bd->bd_BytesPerLine = (UWORD) tidata;
- bd->bd_Flags |= BDF_NEEDLAYOUT;
- } else
- retval--;
- break;
- case BDTA_DisplayHex:
- if(tidata != bd->bd_DisplayHex)
- {
- bd->bd_DisplayHex = (UWORD) tidata;
- bd->bd_Flags |= BDF_NEEDLAYOUT;
- } else
- retval--;
- break;
- case BDTA_ShowASCII:
- if(tidata)
- bd->bd_Flags |= BDF_SHOWASCII;
- else
- bd->bd_Flags &= ~BDF_SHOWASCII;
- bd->bd_Flags |= BDF_NEEDLAYOUT;
- break;
- case BDTA_DisplayWrap:
- if(tidata)
- bd->bd_Flags |= BDF_DISPLAYWRAP;
- else
- bd->bd_Flags &= ~BDF_DISPLAYWRAP;
- bd->bd_Flags |= BDF_NEEDLAYOUT;
- break;
- case BDTA_Found:
- if(bd->bd_Found == (STRPTR) tidata)
- retval--;
- else
- {
- STRPTR ptr = (STRPTR) tidata;
- LONG total,vis,topy;
-
- if(GetDTAttrs(obj,DTA_TotalVert ,&total,
- DTA_VisibleVert,&vis,TAG_END) == 2)
- {
- total -= vis;
-
- topy = (ptr - bd->bd_Buffer) / bd->bd_BytesPerLine;
- if(topy > total)
- topy = total;
- else if(topy < 0)
- topy = 0;
-
- D(bug("topy = %ld, ginfo : %lx\n",topy,msg->ops_GInfo));
- setSuperAttrs(cl,obj,msg->ops_GInfo,DTA_TopVert,topy,TAG_DONE);
- D(bug("after setSuper !\n"));
-
- notifyAttrChanges(obj,msg->ops_GInfo,0,DTA_TopVert,topy,TAG_DONE);
- D(bug("after notify !\n"));
- }
- bd->bd_Found = ptr;
- }
- break;
- default:
- retval--;
- }
- }
-
- DB(("setattrs retval : %ld\n",retval));
- return(retval);
- }
- /*FE*/
-
- /*FS*/ GetA4 ULONG layout(struct ClassBase *cb, Class * cl, Object * obj, struct gpLayout * gpl)
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *) G(obj)->SpecialInfo;
- struct BinaryData *bd = INST_DATA(cl,obj);
-
- struct TextFont *font = bd->bd_Font;
-
- /* Attributes obtained from super-class */
- struct IBox *domain;
-
- ULONG retval = 0;
-
- ENTERING;
-
- /* Get all the attributes that we are going to need for a successful layout */
- if((GetDTAttrs(obj,DTA_Domain, (ULONG) &domain,
- TAG_DONE) == 1))
- {
- /* Lock the global object data so that nobody else can manipulate it */
- ObtainSemaphore (&(si->si_Lock));
-
- retval = si->si_TotVert;
-
- /* We only need to perform layout if we are doing word wrap, or this
- * is the initial layout call */
- if(gpl->gpl_Initial || (bd->bd_Flags & BDF_DISPLAYWRAP))
- {
- const UBYTE displayhexbytes[] = {0,3,5,9};
- const UBYTE displayasciibytes[] = {1,1,2,4};
-
- WORD displayaddr = (bd->bd_BufferLen >= (1<<16)) ? 10 : 6;
- WORD numgroups;
- WORD bytesperline;
- WORD showascii = 0;
- LONG lines;
-
- D(bug("calc new layout values !\n"));
-
- if((bd->bd_Flags & BDF_SHOWASCII) || bd->bd_DisplayHex == BDTDH_NONE)
- showascii = 1;
-
- numgroups =
- bytesperline = bd->bd_BytesPerLine;
-
- if(bd->bd_DisplayHex > 0)
- numgroups >>= (bd->bd_DisplayHex - 1);
-
- /* Note this wrap function doesn't work right with proportional fonts ! */
- if(bd->bd_Flags & BDF_DISPLAYWRAP)
- {
- ULONG chars = domain->Width / bd->bd_Font->tf_XSize;
-
- D(bug("object width : %ld\n",domain->Width));
- D(bug("font width : %ld\n",font->tf_XSize));
- D(bug("chars : %ld\n",chars));
-
- if(chars > displayaddr + showascii)
- {
- bytesperline =
- numgroups = (chars - displayaddr - showascii) / (displayhexbytes[bd->bd_DisplayHex] +
- ((showascii) ? displayasciibytes[bd->bd_DisplayHex] : 0));
-
- if(numgroups < 1)
- numgroups = 1;
- } else
- numgroups = 1;
-
- if(bd->bd_DisplayHex > 0)
- bytesperline = (numgroups) << (bd->bd_DisplayHex - 1);
- }
-
- if(bytesperline < 4)
- {
- bytesperline = 4;
- numgroups = 4 / displayasciibytes[bd->bd_DisplayHex];
- }
-
- lines = (bd->bd_BufferLen / bytesperline) + ((bd->bd_BufferLen % bytesperline) ? 1 : 0) - 1;
-
- bd->bd_LineBytes = displayaddr + numgroups * displayhexbytes[bd->bd_DisplayHex] +
- ((showascii) ? bytesperline : 0) + 1;
- bd->bd_NumGroups = numgroups;
- bd->bd_BytesPerLine = bytesperline;
-
- if(bd->bd_LineBuffer && bd->bd_LineBytes > bd->bd_LineBufferLen)
- {
- FreeMem(bd->bd_LineBuffer,bd->bd_LineBufferLen);
- bd->bd_LineBuffer = NULL;
- }
-
- if(!bd->bd_LineBuffer)
- {
- bd->bd_LineBufferLen = bd->bd_LineBytes;
- bd->bd_LineBuffer = AllocMem(bd->bd_LineBufferLen,MEMF_ANY);
- }
-
- /* Compute the lines and columns type information */
- si->si_VertUnit = font->tf_YSize;
- si->si_VisVert = domain->Height / si->si_VertUnit;
- si->si_TotVert = lines;
-
- si->si_HorizUnit = font->tf_XSize;
- si->si_VisHoriz = domain->Width / font->tf_XSize;
- si->si_TotHoriz = bd->bd_LineBytes;
-
- /* Release the global data lock */
- ReleaseSemaphore(&si->si_Lock);
-
- retval = lines;
-
- D(bug("after releasesem !\n"));
-
- if(gpl->gpl_Initial)
- {
- struct RastPort *rp;
-
- /* Get a pointer to the rastport */
- if((rp = ObtainGIRPort (gpl->gpl_GInfo)))
- {
- struct gpRender gpr;
-
- /* Force a redraw */
- gpr.MethodID = GM_RENDER;
- gpr.gpr_GInfo = gpl->gpl_GInfo;
- gpr.gpr_RPort = rp;
- gpr.gpr_Redraw = GREDRAW_REDRAW;
- DoMethodA (obj, (Msg) &gpr);
-
- /* Release the temporary rastport */
- ReleaseGIRPort (rp);
- }
- }
- } else
- ReleaseSemaphore(&si->si_Lock);
-
- /* Not aborted, so tell the world of our newest attributes */
- notifyAttrChanges (obj, gpl->gpl_GInfo, NULL,
- GA_ID, G(obj)->GadgetID,
-
- DTA_VisibleVert, domain->Height / font->tf_YSize,
- DTA_TotalVert, retval,
- DTA_NominalVert, font->tf_YSize * 25,
- DTA_VertUnit, font->tf_YSize,
-
- DTA_VisibleHoriz, domain->Width / font->tf_XSize,
- DTA_TotalHoriz, bd->bd_LineBytes,
- DTA_NominalHoriz, font->tf_XSize * 80,
- DTA_HorizUnit, font->tf_XSize,
-
- DTA_Title, bd->bd_Name,
- DTA_Busy, FALSE,
- DTA_Sync, TRUE,
- TAG_DONE);
-
- }
-
- LEAVING;
-
- return(retval);
- }
- /*FE*/
-
- /*FS*/ LONG formatline(struct BinaryData *bd,STRPTR *start,STRPTR buf,ULONG num)
- {
- STRPTR bptr = *start;
- STRPTR ptr = bptr;
- STRPTR ptr1 = buf;
- UWORD numadd = (bd->bd_BufferLen > ((1<<16) - 1)) ? 10 : 6;
- UWORD grp;
-
- if(numadd == 10)
- sprintf(ptr1,"%08lx: ",num);
- else
- sprintf(ptr1,"%04lx: ",num);
- ptr1 += numadd;
-
- switch(bd->bd_DisplayHex)
- {
- case BDTDH_BYTE:
- for(grp = 0 ; grp < bd->bd_NumGroups && ptr < bd->bd_BufferEnd ; grp++)
- {
- sprintf(ptr1,"%02lx ",*ptr);
- ptr++;
- ptr1 += 3;
- }
-
- while(grp < bd->bd_NumGroups)
- {
- strcpy(ptr1," ");
- ptr1 += 3;
- ptr++;
- grp++;
- }
- break;
- case BDTDH_WORD:
- for(grp = 0 ; grp < bd->bd_NumGroups && ptr < bd->bd_BufferEnd ; grp++)
- {
- sprintf(ptr1,"%04lx ",*((UWORD *) ptr));
- ptr += sizeof(UWORD);
- ptr1 += 5;
- }
-
- while(grp < bd->bd_NumGroups)
- {
- strcpy(ptr1," ");
- ptr1 += 5;
- ptr += sizeof(UWORD);
- grp++;
- }
- break;
- case BDTDH_LONG:
- for(grp = 0 ; grp < bd->bd_NumGroups && ptr < bd->bd_BufferEnd ; grp++)
- {
- sprintf(ptr1,"%08lx ",*((ULONG *) ptr));
- ptr += sizeof(ULONG);
- ptr1 += 9;
- }
-
- while(grp < bd->bd_NumGroups)
- {
- strcpy(ptr1," ");
- ptr1 += 9;
- ptr += sizeof(ULONG);
- grp++;
- }
- break;
- default:
- ptr += bd->bd_BytesPerLine;
- }
-
- /* write ASCII string */
- if((bd->bd_Flags & BDF_SHOWASCII) ||
- (bd->bd_DisplayHex == BDTDH_NONE))
- {
- while(bptr < ptr && bptr < bd->bd_BufferEnd)
- {
- if(*bptr < 32)
- *ptr1 = '.';
- else
- *ptr1 = *bptr;
- ptr1++;
- bptr++;
- }
-
- while(bptr < ptr)
- {
- *ptr1++ = ' ';
- bptr++;
- }
- }
-
- *start = ptr;
-
- return((LONG) (ptr1 - buf));
- }
- /*FE*/
-
- /*FS*/ ULONG getstring(Class *cl,Object *obj,struct dtbGetString *msg)
- {
- struct BinaryData *bd = INST_DATA(cl,obj);
- struct GadgetInfo *ginfo = msg->dtbgs_GInfo;
- struct Library *ReqToolsBase;
- ULONG retval = 0;
-
- if((ReqToolsBase = OpenLibrary("reqtools.library",38)))
- {
- retval = rtGetString(bd->bd_InputString,sizeof(bd->bd_InputString),
- "Binary Datatype Search String",NULL,
- RT_Window ,(ginfo) ? ginfo->gi_Window : NULL,
- RT_ReqPos ,REQPOS_CENTERWIN,
- RT_LockWindow ,TRUE,
- TAG_DONE);
-
- CloseLibrary(ReqToolsBase);
-
- if(retval)
- {
- bd->bd_Found = bd->bd_Buffer;
- strcpy(bd->bd_SearchString,bd->bd_InputString);
- Forbid();
- DoMethod(obj,msg->dtbgs_SearchMethod,ginfo,bd->bd_SearchString,strlen(bd->bd_SearchString));
- Permit();
- }
- }
-
- return(retval);
- }
- /*FE*/
- /*FS*/ UBYTE *searchstring(UBYTE *buf,LONG len,STRPTR string,LONG slen,LONG direction)
- {
- LONG clen = slen;
- LONG elen = len - slen + 1;
- UBYTE *aptr = buf;
- UBYTE *ptr;
- UBYTE *sptr;
-
- if(direction == 1)
- {
- while(elen > 0 && clen > 0)
- {
- ptr = aptr;
- sptr = string;
- clen = slen;
-
- while((*sptr++ == *ptr++) && clen > 0)
- clen--;
-
- aptr++;
- elen--;
- }
- aptr--;
- } else if(direction == -1)
- {
- while(elen > 0 && clen > 0)
- {
- ptr = aptr;
- sptr = string + slen - 1;
- clen = slen;
-
- while((*sptr-- == *ptr--) && clen > 0)
- clen--;
-
- aptr--;
- elen--;
- }
- aptr++;
- }
-
- if(clen > 0)
- return(NULL);
-
- return(aptr);
- }
- /*FE*/
-
-
-